{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-26T06:14:46.350753Z",
     "start_time": "2025-06-26T06:14:46.346738Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['c:\\\\Program Files\\\\Python312\\\\python312.zip', 'c:\\\\Program Files\\\\Python312\\\\DLLs', 'c:\\\\Program Files\\\\Python312\\\\Lib', 'c:\\\\Program Files\\\\Python312', '', 'C:\\\\Users\\\\41507\\\\AppData\\\\Roaming\\\\Python\\\\Python312\\\\site-packages', 'C:\\\\Users\\\\41507\\\\AppData\\\\Roaming\\\\Python\\\\Python312\\\\site-packages\\\\win32', 'C:\\\\Users\\\\41507\\\\AppData\\\\Roaming\\\\Python\\\\Python312\\\\site-packages\\\\win32\\\\lib', 'C:\\\\Users\\\\41507\\\\AppData\\\\Roaming\\\\Python\\\\Python312\\\\site-packages\\\\Pythonwin', 'c:\\\\Program Files\\\\Python312\\\\Lib\\\\site-packages']\n"
     ]
    }
   ],
   "source": [
    "import sys\n",
    "print(sys.path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-26T06:14:48.340332Z",
     "start_time": "2025-06-26T06:14:46.350753Z"
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.datasets import fetch_california_housing\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "from tqdm.auto import tqdm\n",
    "from torch.utils.data import DataLoader, Dataset\n",
    "from deeplearning_func import EarlyStopping, ModelSaver\n",
    "from deeplearning_func import plot_learning_loss_curves,train_regression_model,evaluate_regression_model\n",
    "import os"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-26T06:14:48.358208Z",
     "start_time": "2025-06-26T06:14:48.340332Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "训练集大小: 13209\n",
      "验证集大小: 3303\n",
      "测试集大小: 4128\n"
     ]
    }
   ],
   "source": [
    "\n",
    "\n",
    "# 加载加利福尼亚房价数据集\n",
    "housing = fetch_california_housing()\n",
    "X = housing.data\n",
    "y = housing.target\n",
    "\n",
    "# 数据拆分：训练集(60%)、验证集(20%)、测试集(20%)\n",
    "X_train_val, X_test, y_train_val, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\n",
    "X_train, X_val, y_train, y_val = train_test_split(X_train_val, y_train_val, test_size=0.2, random_state=42)  # 0.25 x 0.8 = 0.2\n",
    "\n",
    "print(f\"训练集大小: {X_train.shape[0]}\")\n",
    "print(f\"验证集大小: {X_val.shape[0]}\")\n",
    "print(f\"测试集大小: {X_test.shape[0]}\")\n",
    "\n",
    "# 数据标准化\n",
    "scaler = StandardScaler()\n",
    "X_train_scaled = scaler.fit_transform(X_train)\n",
    "X_val_scaled = scaler.transform(X_val)\n",
    "X_test_scaled = scaler.transform(X_test)\n",
    "\n",
    "# 自定义数据集类\n",
    "class HousingDataset(Dataset):\n",
    "    def __init__(self, features, targets):\n",
    "        self.features = torch.FloatTensor(features)\n",
    "        self.targets = torch.FloatTensor(targets).view(-1, 1)\n",
    "        \n",
    "    def __len__(self):\n",
    "        return len(self.features) #返回样本数量\n",
    "    \n",
    "    def __getitem__(self, idx): #传入索引，返回对应索引样本的特征和目标\n",
    "        return self.features[idx], self.targets[idx]\n",
    "\n",
    "# 创建数据集实例\n",
    "train_dataset = HousingDataset(X_train_scaled, y_train)\n",
    "val_dataset = HousingDataset(X_val_scaled, y_val)\n",
    "test_dataset = HousingDataset(X_test_scaled, y_test)\n",
    "\n",
    "# 创建数据加载器\n",
    "train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)\n",
    "val_loader = DataLoader(val_dataset, batch_size=32)\n",
    "test_loader = DataLoader(test_dataset, batch_size=32)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 加载数据，构建模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-26T06:14:49.085821Z",
     "start_time": "2025-06-26T06:14:48.358208Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WideDeepModel(\n",
      "  (deep): Sequential(\n",
      "    (0): Linear(in_features=8, out_features=30, bias=True)\n",
      "    (1): ReLU()\n",
      "    (2): Linear(in_features=30, out_features=30, bias=True)\n",
      "    (3): ReLU()\n",
      "  )\n",
      "  (output): Linear(in_features=38, out_features=1, bias=True)\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "from torch import optim\n",
    "\n",
    "\n",
    "\n",
    "# 定义神经网络模型\n",
    "class WideDeepModel(nn.Module):\n",
    "    def __init__(self, input_dim):\n",
    "        super().__init__()\n",
    "        # Deep部分使用Sequential\n",
    "        self.deep = nn.Sequential(\n",
    "            nn.Linear(input_dim, 30),\n",
    "            nn.ReLU(),\n",
    "            nn.Linear(30, 30),\n",
    "            nn.ReLU()\n",
    "        )\n",
    "        \n",
    "        # Wide部分直接使用原始输入\n",
    "        \n",
    "        # 输出层，输入维度是deep部分的30 + wide部分的input_dim\n",
    "        self.output = nn.Linear(30 + input_dim, 1)\n",
    "        \n",
    "    def forward(self, x):\n",
    "        # Deep路径，deep shape是[batch_size, 30]\n",
    "        deep = self.deep(x)\n",
    "        \n",
    "        # Wide路径直接使用原始输入\n",
    "        wide = x\n",
    "        \n",
    "        # 连接Wide和Deep,combined shape是[batch_size, 30 + input_dim]\n",
    "        combined = torch.cat([wide, deep], dim=1)\n",
    "        \n",
    "        # 输出层，输出shape是[batch_size, 1]\n",
    "        output = self.output(combined)\n",
    "        return output\n",
    "\n",
    "# 初始化模型、损失函数和优化器\n",
    "input_dim = X_train.shape[1]\n",
    "model = WideDeepModel(input_dim)\n",
    "criterion = nn.MSELoss()\n",
    "optimizer = optim.Adam(model.parameters())\n",
    "\n",
    "# 打印模型结构\n",
    "print(model)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-26T06:15:20.191876Z",
     "start_time": "2025-06-26T06:14:49.089839Z"
    }
   },
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "e2036fdece8c42a6a370d7aa00abb027",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "train progress:   0%|          | 0/41300 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "早停触发! 最佳验证准确率(如果是回归，这里是损失): -0.2886\n",
      "早停: 已有10轮验证损失没有改善！\n"
     ]
    }
   ],
   "source": [
    "\n",
    "\n",
    "\n",
    "# 训练模型\n",
    "# 初始化早停和模型保存对象\n",
    "early_stopping = EarlyStopping(patience=10, verbose=True)\n",
    "model_saver = ModelSaver(save_dir='model_weights')\n",
    "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n",
    "model, record_dict = train_regression_model(\n",
    "    model=model,\n",
    "    train_loader=train_loader,\n",
    "    val_loader=val_loader,\n",
    "    criterion=criterion,\n",
    "    optimizer=optimizer,\n",
    "    num_epochs=100,\n",
    "    print_every=10,\n",
    "    eval_step=500,\n",
    "    early_stopping=early_stopping,\n",
    "    model_saver=model_saver,\n",
    "    device=device\n",
    ")\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-26T06:15:20.355745Z",
     "start_time": "2025-06-26T06:15:20.192889Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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Ld99953p7dPQ66HHDR3CX7KscVnHFO0x1KqEa9asCdh+wx7tpCx64VaVPKZUtnZCCCon7frr1q2bzJw5s1j3on7cq1evwscuuugi01V4yy23yKeffmrR3sIudFiKXlHRqysetBEUpUOb9MSk6LElOTnZVIkremxROgfk+eefN21IK/8guO3cudPMCSp6fFG0k8pN55Tqie1XX31levv0GFKUnquEh4cXO6boECedn1rymKLt5IYbbjBX/yvLCS68aydl8awxVvKYUtnaCcPhToGWx9ZG0L17d9MtOH78eFNq8MYbbyz2vBEjRshHH30k1113nYSFhclll11m2T4jsB566CGzzocOgdOSpFpOXXsQdXhKUbSR4AvDRa+saTEE/WOjE1R1srKO1X7mmWfMeGv9Q/X444+bMdq6rkNJWlBD5ycOGzZMpk6dKn369AnwTwMr2oluOsdQ13vR0KwXV/76179K8+bNTTn1kmgnlXtok15I+/rrr81cU888H537pcMf9VaHX+s5i7ab+Ph40x40AJ155pmlvt6LL75o2sp5551nhlaytl1wtJPNmzebz2vPsa4npb3HOly/b9++ZRZrqlTtxOrydBXVq6++6mrYsKErIiLClMxesGDBcUuaTpo0yRUVFeX64osvLNpbBNqVV17pqlOnjmkf9erVMx9v2rSp8PO0keDkKTNactOSx54y2Y8//rirVq1apjT2+eef71q/fv1xSx+rl156yRUXF+eaO3euJT8TAttO0tPTXQMHDnTVqFHDlD9u1KiR69Zbb3Xt3bu38P/TToJDWW1Et/fff7/wORkZGa677rrLVa1aNZfT6XSNGDHCtWfPnuOWPlb33HOP+ftV9NiDyttOtm/f7urbt68rISHB/N1p3ry56+GHH3YlJSVV+nbi0H+sDmIAAAAAECjMCQIAAAAQVAhBAAAAAIIKIQgAAABAUCEEAQAAAAgqhCAAAAAAQYUQBAAAACCoEIIAAAAABBVCEAAAAICgQggCAAAAEFQIQQCACmHUqFEyfPhwq3cDAFAJEIIAAAAABBVCEADAViZPniwdOnSQ6OhoqV69uvTv318efvhh+eCDD+Trr78Wh8Nhtl9//dU8f8eOHXLFFVdI1apVJSEhQS6++GLZunVrqR6ksWPHSo0aNSQ+Pl7uuOMOyc7OtvCnBABYKczS7w4AQBF79uyRq6++Wl544QUZMWKEpKSkyJw5c+T666+X7du3S3Jysrz//vvmuRp4cnJyZNCgQdKrVy/zvLCwMHnmmWdk8ODBsmLFComIiDDPnTlzpkRFRZngpAHpxhtvNAHr2WeftfgnBgBYgRAEALBVCMrNzZVLLrlEGjVqZB7TXiGlPUNZWVlSu3btwud//PHHkp+fL++8847pHVIakrRXSAPPwIEDzWMaht577z1xOp3Srl07eeqpp0zv0tNPPy0hIQyKAIBgw5EfAGAbnTp1kvPPP98En8svv1zefvttOXLkyHGf/8cff8imTZskLi5OYmNjzaY9RJmZmbJ58+ZiX1cDkIf2HKWmppqhdACA4ENPEADANkJDQ2XGjBkyb948mT59urz66qvy97//XRYuXFjm8zXIdOvWTf73v/+V+pzO/wEAoCyEIACAreiwtt69e5vtiSeeMMPivvrqKzOkLS8vr9hzu3btKpMmTZKaNWuaggcn6jHKyMgwQ+rUggULTK9RgwYN/P7zAADsh+FwAADb0B6f5557TpYsWWIKIXz55Zdy4MABadOmjTRu3NgUO1i/fr0cPHjQFEW45pprJDEx0VSE08IIW7ZsMXOB7r33Xtm5c2fh19VKcDfffLOsWbNGfvjhB3nyySfl7rvvZj4QAAQpeoIAALahvTmzZ8+W8ePHm0pw2gv00ksvyZAhQ6R79+4m4OitDoP75ZdfpF+/fub5jzzyiCmmoNXk6tWrZ+YVFe0Z0o9btGghffv2NcUVtALdmDFjLP1ZAQDWcbhcLpeF3x8AAL/SdYKOHj0qU6ZMsXpXAAA2wTgAAAAAAEGFEAQAAAAgqDAcDgAAAEBQoScIAAAAQFAhBAEAAAAIKoQgAAAAAEGFEAQAAAAgqBCCAAAAAAQVQhAAAACAoEIIAgAAABBUCEEAAAAAJJj8P0vZ5zv0kstzAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 1000x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#画图\n",
    "plot_learning_loss_curves(record_dict,sample_step=500)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-26T06:15:20.412545Z",
     "start_time": "2025-06-26T06:15:20.356836Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "测试集上的损失为0.2999\n"
     ]
    }
   ],
   "source": [
    "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n",
    "test_loss=evaluate_regression_model(model,test_loader,device,criterion)\n",
    "print(f\"测试集上的损失为{test_loss:.4f}\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
